#include "Logger.h"

#include <spdlog/spdlog.h>

namespace GiSo {
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>

std::shared_ptr<spdlog::logger> Logger::m_logger;

void Logger::init(const Options& options) {
    spdlog::init_thread_pool(8192, 1); // Initialize thread pool

    std::vector<spdlog::sink_ptr> sinks;

    if (options.outputType == OutputType::Console || options.outputType == OutputType::Both) {
        auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        sinks.push_back(console_sink);
    }

    if (options.outputType == OutputType::File || options.outputType == OutputType::Both) {
        auto rotating_file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
            options.filename, options.maxFileSize, options.maxFiles);
        sinks.push_back(rotating_file_sink);
    }

    m_logger = std::make_shared<spdlog::async_logger>("async_logger", sinks.begin(), sinks.end(),
        spdlog::thread_pool(), spdlog::async_overflow_policy::block);

    m_logger->set_level(options.level);
    spdlog::register_logger(m_logger);
}

std::shared_ptr<spdlog::logger> Logger::getLogger() {
    if (!m_logger) {
        Options defaultOptions;
        init(defaultOptions);
    }
    return m_logger;
}

} // namespace GiSo